from datetime import datetime
from django.http import HttpResponse, HttpResponseRedirect
from ext.BeautifulSoup import BeautifulSoup
from google.appengine.api import memcache, users
from google.appengine.ext import db
from looptube.controllers import getChannelDict, getChannelNameDict
from looptube.models import CronJob, RadioLog, Playlist, VideoInfo, PlaylistVideo
from looptube.utils import fetchWebPage
from random import seed, shuffle
from urllib import urlencode
from datetime import datetime
from time import time

CronJobsData = {'fetchQRadioInfo' : {'interval' : 60},
                'fetchXM45RadioInfo' : {'interval' : 60},
                'fetchXM47RadioInfo' : {'interval' : 60},
                'fetchXM20RadioInfo' : {'interval' : 60},
                'fetchXM30RadioInfo' : {'interval' : 60},
                'fetchXM31RadioInfo' : {'interval' : 60},
                'fetchXM71RadioInfo' : {'interval' : 60},
                'makeChannelPlaylist_britfashion' : {'interval' : 3600},
                'makeChannelPlaylist_nobel' : {'interval' : 3600},
                'makeChannelPlaylist_altcafe' : {'interval' : 3600},
                'makeChannelPlaylist_tophits' : {'interval' : 3600},
                'makeChannelPlaylist_liquid' : {'interval' : 3600},
                'makeChannelPlaylist_globalpop' : {'interval' : 3600},
                'makeChannelPlaylist_hits2k' : {'interval' : 3600},
                }

#functions

def fetchXMRadioInfo(radioName, channelNumber):
    try:
        url = 'http://www.xmradio.com/padData/pad_provider.jsp?channel=%d' % (int(channelNumber))
        xml = fetchWebPage(url, 'GET')
    except:
        xml = """
<?xml version="1.0" encoding="UTF-8"?>
<paddata>
    <authenticateduser>true</authenticateduser>
  <event>
        <artist></artist>
        <album></album>
        <songtitle></songtitle> 
        <channelnumber>47</channelnumber>
        <channelname>Ethel</channelname>
        <trackId>0</trackId>
        <albumId>0</albumId>
        <artistId>0</artistId>
        <linkURL></linkURL>
  </event>        
</paddata>
"""

    if ((None == xml) or ('' == xml)):
        return 'fetch failed!'
    
    soup = BeautifulSoup(xml)
    try:
        return RadioLog.logRadio(radioName, unicode(soup.find('artist').string), unicode(soup.find('songtitle').string))
    except:
        return 'fetch failed!'

def makeChannelPlaylist(channelName):
    result = ''
    channelDict = getChannelDict()
    channelNameDict = getChannelNameDict()
    radioName = channelDict[channelName]
    videoInfos = RadioLog.getRadioThisHourVideoInfos(radioName)
    result = result + '<p>%s: %d</p><ul>' % (radioName, len(videoInfos))
    videoIDList = []
    for videoInfo in videoInfos:
        result = result + '<li>%s</li>' % videoInfo.title
        videoIDList.append(videoInfo.videoID)
    result = result + '</ul>'
    if (len(videoIDList) > 0):
        videoIDs = ','.join(videoIDList)
        user = users.User('looptube@gmail.com')
        now = time()
        dt = datetime.fromtimestamp(now-3600)
        playlistTitle = "LoopTube Channel Playlist: %s, %s #%d" % (channelNameDict[channelName], dt.strftime('%Y/%m/%d'), int(dt.hour)+1)
        playlist = Playlist.create(playlistTitle, videoIDs, user, channelName=channelName)
        return 'playlists made successfully with %d videos!' % len(videoIDList)
    else:
        return 'no new videos in this hour!'
    #return result

# cron jobs

def fetchQRadioInfo(request):
    radioName='QRadio'
    
    try:
        url = 'http://radioplayer.qthemusic.com/cgi-bin/nowplaying.pl'
        payload = '{"starttime":null}'
        headers = {'Content-Type': 'application/json'}
        json = fetchWebPage(url, 'POST', payload, headers)
    except:
        json = '{"itunesurl":"http://clk.tradedoubler.com/click?p=23708&a=1341145&epi=q%20radio%20player%20dls%20-%20Longggpigs%20-%20Farss&url=http%3A%2F%2Fphobos.apple.com%2FWebObjects%2FMZSearch.woa%2Fwa%2FadvancedSearchResults%3FartistTerm%3DLongpigs%26albumTerm%3D%26songTerm%3DFar%26s%3D143444%26partnerId%3D2003","artist":"Longpissgs","song":"feafe","itemcode":"QM00591","seconds_until_refresh":143,"image":"","amazonurl":""}'

    if ((None == json) or ('' == json)):
        return 'fetch failed!'
    
    exec('resultDict = '+json)
    return RadioLog.logRadio(radioName, resultDict['artist'], resultDict['song'])

def fetchXM20RadioInfo(request):
    radioName = 'XM-20-20'
    return fetchXMRadioInfo(radioName, 20)

def fetchXM30RadioInfo(request):
    radioName = 'XM-Pop2K'
    return fetchXMRadioInfo(radioName, 30)

def fetchXM31RadioInfo(request):
    radioName = 'XM-UPop'
    return fetchXMRadioInfo(radioName, 31)

def fetchXM71RadioInfo(request):
    radioName = 'XM-Watercolors'
    return fetchXMRadioInfo(radioName, 71)

def fetchXM47RadioInfo(request):
    radioName = 'XM-Ethel'
    return fetchXMRadioInfo(radioName, 47)

def fetchXM45RadioInfo(request):
    radioName = 'XM-Cafe'
    return fetchXMRadioInfo(radioName, 45)

def makeChannelPlaylist_britfashion(request):
    return makeChannelPlaylist('britfashion')

def makeChannelPlaylist_nobel(request):
    return makeChannelPlaylist('nobel')

def makeChannelPlaylist_altcafe(request):
    return makeChannelPlaylist('altcafe')

def makeChannelPlaylist_tophits(request):
    return makeChannelPlaylist('tophits')

def makeChannelPlaylist_liquid(request):
    return makeChannelPlaylist('liquid')

def makeChannelPlaylist_globalpop(request):
    return makeChannelPlaylist('globalpop')

def makeChannelPlaylist_hits2k(request):
    return makeChannelPlaylist('hits2k')

# actions

def tempJobAction(request):
    playlistVideos = PlaylistVideo.all()
    playlistVideos = playlistVideos.fetch(playlistVideos.count())
    keys = {}
    numDeletedItems = 0
    result = '<p>%d playlistVideos</p>' % len(playlistVideos)
    for playlistVideo in playlistVideos:
        try:
            playlistKey = str(playlistVideo.playlist.key())
        except:
            playlistVideo.delete()
            numDeletedItems = numDeletedItems + 1
            continue
        videoID = playlistVideo.videoID
        if (keys.__contains__(playlistKey)):
            if (keys[playlistKey].__contains__(videoID)):
                playlistVideo.delete()
                numDeletedItems = numDeletedItems + 1
            else:
                keys[playlistKey][videoID] = True
        else:
            keys[playlistKey] = { videoID : True }
                
    result = result + '<p>deleted %d items!</p>' % numDeleteItems
    return HttpResponse(result)
        
def runAction(request):
    remoteAddr = request.META['REMOTE_ADDR']
    #if ((not remoteAddr.startswith('140.113.')) and (remoteAddr != '127.0.0.1')):
    #    resultText = resultText + '<p>Access denied!</p>\n'
    #    return HttpResponse(resultText)
    
    if (request.GET.__contains__('jobs')):
        jobList = request.GET['jobs'].split(',')
        resultText = request.GET['resultText']
        currJob = jobList[0]
        del jobList[0]
        jobdata = CronJobsData[currJob]
        lockName = 'Cron_'+currJob
        lockResult = memcache.add(lockName, 1, 10)
        if (True == lockResult):
            cronjobs = CronJob.gql('WHERE name=:name', name=currJob)
            if (cronjobs.count() == 0):
                # initialize cron job
                cronjob = CronJob(name=currJob, interval=jobdata['interval'], lastRun=datetime.strptime('20080101', '%Y%m%d'))
                cronjob.put()
            else:
                cronjob = cronjobs.fetch(1)[0]
                if (cronjob.interval != jobdata['interval']):
                    # update interval
                    cronjob.interval = jobdata['interval']
                    cronjob.lastRun = datetime.strptime('20080101', '%Y%m%d')

            if (#(remoteAddr == '127.0.0.1') or 
                True == CronJob.checkInterval(cronjob.lastRun, cronjob.interval)):
                cronjob.lastRun = datetime.now()
                cronjob.put()
                exec('result = %s(request)' % (currJob))
                resultText = resultText + ('<p>%s: run job result: %s</p>\n' % (currJob, result))
            else:
                resultText = resultText + ('<p>%s: interval not reached yet.</p>\n' % (currJob))
            memcache.delete(lockName)
        else:
            resultText = resultText + ('<p>%s: job locked, skipped.</p>\n' % (currJob))
    else:
        resultText = '<p>Your IP: %s</p>\n' % remoteAddr
        resultText = resultText + '<p>Time Now: %s</p>\n' % (datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
        seed()
        jobList = CronJobsData.keys()
        shuffle(jobList)

    if (len(jobList) > 0):
        return HttpResponseRedirect('/cron/run?%s' % urlencode({'jobs' : ','.join(jobList), 'resultText' : resultText}))
    else:
        return HttpResponse(resultText + '<p>runAll completed! <a href="/cron/run">Run Again</a></p>')
